local single_child_view = require 'views.single_child_view'
local padding = require 'padding'
local vec2 = require 'vec2'
local constraints_type = require 'constraints'
local constrained_size = require 'constrained_size'
local rect = require 'rect'

---@class padded: single_child_view
---@field padding padding
local padded = single_child_view:new_view_type()

---@class padded.renderer: single_child_view.renderer
padded.renderer = single_child_view.renderer:new_renderer_type()

---@param options { padding: padding, child: view }
---@return padded
function padded:__call(options)
    self:set_view_prototype(options)
    options.padding = options.padding or padding.all(0)

    return options
end

---@param constraints constraints
---@param view padded
function padded.renderer:layout(constraints, view)
    local padding_size = vec2(
        view.padding.left + view.padding.right,
        view.padding.bottom + view.padding.top
    )

    local child_constraints = constraints_type.new(
        vec2(0):max(constraints.min_size - padding_size),
        vec2(0):max(constraints.max_size - padding_size)
    )

    local child_size = self.child_renderer:layout(child_constraints, view.child)
    local result_size = constrained_size.unconstrained()

    if not child_size.width_unconstrained then
        result_size:set_constrained_width(child_size.width + padding_size.x)
    end

    if not child_size.height_unconstrained then
        result_size:set_constrained_height(child_size.height + padding_size.y)
    end

    return result_size
end

---@param render_rect rect
---@param view padded
function padded.renderer:render(render_rect, view)
    local padding = view.padding
    local rect_size = render_rect:size()
    local render_rect = rect.from_bottom_left(
        vec2(render_rect:left() + padding.left, render_rect:bottom() + padding.bottom),
        vec2(
            rect_size.x - (padding.left + padding.right),
            rect_size.y - (padding.bottom + padding.top)
        )
    )

    self.child_renderer:render(render_rect, view.child)
end

return padded
